package service

import (
	"context"
	"errors"
	"fmt"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"zorm-learn/app/dm/model"
)

// SaveTestLongStrStruct 保存
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveTestLongStrStruct(ctx context.Context, testlongstrstruct *model.TestLongStrStruct) error {

	// testlongstrstruct对象指针不能为空
	if testlongstrstruct == nil {
		return errors.New("testlongstrstruct对象指针不能为空")
	}
	//匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveTestLongStrStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始

		_, errSaveTestLongStrStruct := zorm.Insert(ctx, testlongstrstruct)

		if errSaveTestLongStrStruct != nil {
			return nil, errSaveTestLongStrStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveTestLongStrStruct != nil {
		errSaveTestLongStrStruct := fmt.Errorf("service.SaveTestLongStrStruct错误:%w", errSaveTestLongStrStruct)
		logger.Error(errSaveTestLongStrStruct)
		return errSaveTestLongStrStruct
	}

	return nil
}

// UpdateTestLongStrStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateTestLongStrStruct(ctx context.Context, testlongstrstruct *model.TestLongStrStruct) error {

	// testlongstrstruct对象指针或主键Id不能为空
	if testlongstrstruct == nil {
		return errors.New("testlongstrstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTestLongStrStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTestLongStrStruct := zorm.Update(ctx, testlongstrstruct)

		if errUpdateTestLongStrStruct != nil {
			return nil, errUpdateTestLongStrStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTestLongStrStruct != nil {
		errUpdateTestLongStrStruct := fmt.Errorf("service.UpdateTestLongStrStruct错误:%w", errUpdateTestLongStrStruct)
		logger.Error(errUpdateTestLongStrStruct)
		return errUpdateTestLongStrStruct
	}

	return nil
}

// UpdateNotZeroTestLongStrStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroTestLongStrStruct(ctx context.Context, testlongstrstruct *model.TestLongStrStruct) error {

	// testlongstrstruct对象指针或主键Id不能为空
	if testlongstrstruct == nil {
		return errors.New("testlongstrstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTestLongStrStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTestLongStrStruct := zorm.UpdateNotZeroValue(ctx, testlongstrstruct)

		if errUpdateTestLongStrStruct != nil {
			return nil, errUpdateTestLongStrStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTestLongStrStruct != nil {
		errUpdateTestLongStrStruct := fmt.Errorf("service.UpdateNotZeroTestLongStrStruct错误:%w", errUpdateTestLongStrStruct)
		logger.Error(errUpdateTestLongStrStruct)
		return errUpdateTestLongStrStruct
	}

	return nil
}

// DeleteTestLongStrStructById 根据Id删除
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteTestLongStrStructById(ctx context.Context, id string) error {

	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteTestLongStrStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(model.TestLongStrStructTableName).Append(" WHERE id=?", id)
		_, errDeleteTestLongStrStruct := zorm.UpdateFinder(ctx, finder)

		if errDeleteTestLongStrStruct != nil {
			return nil, errDeleteTestLongStrStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errDeleteTestLongStrStruct != nil {
		errDeleteTestLongStrStruct := fmt.Errorf("service.DeleteTestLongStrStruct错误:%w", errDeleteTestLongStrStruct)
		logger.Error(errDeleteTestLongStrStruct)
		return errDeleteTestLongStrStruct
	}

	return nil
}

// FindTestLongStrStructById 根据Id查询信息
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTestLongStrStructById(ctx context.Context, id string) (*model.TestLongStrStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}

	//根据Id查询
	finder := zorm.NewSelectFinder(model.TestLongStrStructTableName).Append(" WHERE id=?", id)
	testlongstrstruct := model.TestLongStrStruct{}
	has, errFindTestLongStrStructById := zorm.QueryRow(ctx, finder, &testlongstrstruct)

	//记录错误
	if errFindTestLongStrStructById != nil {
		errFindTestLongStrStructById := fmt.Errorf("service.FindTestLongStrStructById错误:%w", errFindTestLongStrStructById)
		logger.Error(errFindTestLongStrStructById)
		return nil, errFindTestLongStrStructById
	}

	if !has {
		return nil, nil
	}

	return &testlongstrstruct, nil

}

// FindTestLongStrStructList 根据Finder查询列表
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTestLongStrStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]model.TestLongStrStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	testlongstrstructList := make([]model.TestLongStrStruct, 0)
	errFindTestLongStrStructList := zorm.Query(ctx, finder, &testlongstrstructList, page)

	//记录错误
	if errFindTestLongStrStructList != nil {
		errFindTestLongStrStructList := fmt.Errorf("service.FindTestLongStrStructList错误:%w", errFindTestLongStrStructList)
		logger.Error(errFindTestLongStrStructList)
		return nil, errFindTestLongStrStructList
	}

	return testlongstrstructList, nil
}
